import { useEffect, useRef } from 'react'
import { Graph, Shape } from '@antv/x6'
import styles from './index.module.less'
import LeftPanel from './LeftPanel'
import Canvas from './Canvas'
import ConfigPanel from './ConfigPanel'
import Toolbar from './Toolbar'
import { Snapline } from '@antv/x6-plugin-snapline'
import { History } from '@antv/x6-plugin-history'
import { Selection } from '@antv/x6-plugin-selection'
import { useProcessMiningEngineStore } from './store'
import clsx from 'clsx'
import { DoubleLeft, DoubleRight } from '@terminus/nusi-slim-icons'

const ProcessMiningEngine = () => {
  const graphRef = useRef<Graph | null>(null)
  const { setGraph, containerRef, leftSidebarVisible, setLeftSidebarVisible, rightSidebarVisible, setRightSidebarVisible } = useProcessMiningEngineStore()

  useEffect(() => {
    if (!containerRef || !containerRef.current) return

    // 创建画布
    const graph = new Graph({
      container: containerRef.current,
      background: {
        color: '#fff',
      },
      grid: {
        visible: true,
        type: 'dot',
        args: {
          color: '#e0e0e0',
          thickness: 1,
        },
      },
      panning: {
        enabled: true,
        eventTypes: ['leftMouseDown', 'mouseWheel'],
      },
      mousewheel: {
        enabled: true,
        zoomAtMousePosition: true,
        modifiers: 'ctrl',
        minScale: 0.5,
        maxScale: 4,
      },
      connecting: {
        router: 'manhattan',
        connector: {
          name: 'rounded',
          args: {
            radius: 8,
          },
        },
        anchor: 'center',
        connectionPoint: 'anchor',
        allowBlank: false,
        snap: {
          radius: 20,
        },
        createEdge() {
          return new Shape.Edge({
            attrs: {
              line: {
                stroke: '#A2B1C3',
                strokeWidth: 2,
                targetMarker: {
                  name: 'block',
                  width: 12,
                  height: 10,
                },
              },
            },
            zIndex: 0,
          })
        },
        validateConnection({ targetMagnet }) {
          return !!targetMagnet
        },
      },
      highlighting: {
        magnetAdsorbed: {
          name: 'stroke',
          args: {
            attrs: {
              fill: '#5F95FF',
              stroke: '#5F95FF',
            },
          },
        },
      },
    })

    // 开启对齐线插件
    graph.use(
      new Snapline({
        enabled: true,
      }),
    )

    // 开启历史记录插件,可以使用撤销和重做
    graph.use(
      new History({
        enabled: true,
      }),
    )

    // 开启选择插件,可以使用选择和取消选择
    graph.use(
      new Selection({
        enabled: true,
        // rubberband: true,
        showNodeSelectionBox: true,
      }),
    )

    graphRef.current = graph

    // 控制连接桩显示/隐藏
    const showPorts = (ports: NodeListOf<SVGElement>, show: boolean) => {
      for (let i = 0, len = ports.length; i < len; i += 1) {
        ports[i].style.visibility = show ? 'visible' : 'hidden'
      }
    }
    graph.on('node:mouseenter', () => {
      if (!containerRef?.current) return
      const container = document.getElementById(containerRef?.current?.id as string)
      if (!container) return
      const ports = container.querySelectorAll(
        '.x6-port-body',
      ) as NodeListOf<SVGElement>
      showPorts(ports, true)
    })
    graph.on('node:mouseleave', () => {
      if (!containerRef?.current) return
      const container = document.getElementById(containerRef?.current?.id as string)
      if (!container) return
      const ports = container.querySelectorAll(
        '.x6-port-body',
      ) as NodeListOf<SVGElement>
      showPorts(ports, false)
    })

    setGraph(graph)

    return () => {
      graph.dispose()
      setGraph(null)
    }
  }, [setGraph, containerRef])

  return (
    <div className={styles.ProcessMiningEngine}>
      <div className={clsx(styles.leftPanel, !leftSidebarVisible && styles.leftPanelHidden)}>
        <LeftPanel />
      </div>
      <div className={styles.centerPanel}>
        <div className={styles.centerPanelHeader}>
          <div onClick={() => setLeftSidebarVisible(!leftSidebarVisible)} className={clsx(styles.leftPanelToggle, !leftSidebarVisible && styles.leftPanelToggleRotated)}>
            <DoubleRight size="10px" />
          </div>
          <div className={styles.centerPanelTitle}>
            销售流程
          </div>
          <div onClick={() => setRightSidebarVisible(!rightSidebarVisible)} className={clsx(styles.rightPanelToggle, !rightSidebarVisible && styles.rightPanelToggleRotated)}>
            <DoubleLeft size="10px" />
          </div>
        </div>
        <div className={styles.centerPanelContent}>
          <Canvas />
          <Toolbar />
        </div>
      </div>
      <div className={clsx(styles.rightPanel, !rightSidebarVisible && styles.rightPanelHidden)}>
        <ConfigPanel />
      </div>
    </div>
  )
}

export default ProcessMiningEngine
